
/*
    Software License

    Copyright (C) 2021-05-24  Xoronos

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, version 3.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

/*
    Liabilities

    The software is provided "AS IS" without any warranty of any kind, either expressed,
    implied, or statutory, including, but not limited to, any warranty that the software
    will conform to specifications, any implied warranties of merchantability, fitness
    for a particular purpose, and freedom from infringement, and any warranty that the
    documentation will conform to the software, or any warranty that the software will
    be error free.

    In no event shall Xoronos be liable for any damages, including, but not limited to,
    direct, indirect, special or consequential damages, arising out of, resulting from,
    or in any way connected with this software, whether or not based upon warranty,
    contract, tort, or otherwise, whether or not injury was sustained by persons or
    property or otherwise, and whether or not loss was sustained from, or arose out of
    the results of, or use of, the software or services provided hereunder.

    To request the provided software under a different license you can contact us at
    support@xoronos.com
*/

#include "test_keys.h"

int test_sym_key_gen(
 )
{
    char fname[256];

    xmonomial_key_t mkey;
    int error;

    FILE *fp;
    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    strcpy( fname, "../cache/to_remove_monomic_key.txt" );
    xrn_make_monomial_key( &mkey, settings );
    fp = fopen( fname, "wb" );
    xrn_dump_monomial_key( mkey, fp, settings );
    fclose( fp );
    fp = fopen( fname, "rb" );
    error = xrn_load_monomial_key( &mkey, fp, &settings );
    fclose( fp );
    remove( fname );
    return error;
}

int test_certificate_sym(
 )
{
    FILE *fp;
    xcertificate_sym_t cert, cert2;
    time_t t;
    int error, i;
    char fname1[256];
    char fname2[256];

    xrn_crypto_extra_settings_t settings;

    for ( i = 0; i < sizeof( cert ); i++ ) {
        ( ( uint8_t * ) & cert )[i] = 0;
        ( ( uint8_t * ) & cert2 )[i] = 0;
    }

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    strcpy( fname1, "../cache/to_remove_certificate_sym_1.txt" );
    strcpy( fname2, "../cache/to_remove_certificate_sym_2.txt" );
    strcpy( cert.subject, "blablabla bla" );
    for ( i = 0; i < XRN_STATE_KEY_SIZE; i++ ) {
        xrn_initialize_rnd_num( &cert.monovalent_key.state[i] );
    }

    cert.monovalent_key.start_timestamp = 0;
    cert.monovalent_key.end_timestamp = 0xffffffffffffffff;

    cert.start_timestamp = ( uint64_t ) time( &t );
    cert.end_timestamp = ( uint64_t ) time( &t ) + 10000;
    xrn_initialize_rnd_num( &cert.signature.proof );
    fp = fopen( fname1, "wb" );
    xrn_dump_certificate_sym( cert, fp, settings );
    fclose( fp );
    fp = fopen( fname1, "rb" );
    xrn_load_certificate_sym( &cert2, fp, &settings );
    fclose( fp );
    fp = fopen( fname2, "wb" );
    xrn_dump_certificate_sym( cert2, fp, settings );
    fclose( fp );
    for ( i = 0; i < XRN_STATE_KEY_SIZE; i++ ) {
        XNUM_CMP( cert.monovalent_key.state[i], cert2.monovalent_key.state[i], error );
        if ( error ) {
            remove( fname1 );
            remove( fname2 );
            return 1;
        }

    }

    error = cert.monovalent_key.start_timestamp != cert2.monovalent_key.start_timestamp;
    if ( error ) {
        remove( fname1 );
        remove( fname2 );
        return 1;
    }

    error = cert.monovalent_key.end_timestamp != cert2.monovalent_key.end_timestamp;
    if ( error ) {
        remove( fname1 );
        remove( fname2 );
        return 1;
    }

    XNUM_CMP( cert.signature.proof, cert2.signature.proof, error );
    if ( error ) {
        remove( fname1 );
        remove( fname2 );
        return 1;
    }

    XNUM_CMP( cert.signature.hint, cert2.signature.hint, error );
    if ( error ) {
        remove( fname1 );
        remove( fname2 );
        return 1;
    }

    error += cert.end_timestamp != cert2.end_timestamp;
    error += cert.start_timestamp != cert2.start_timestamp;
    if ( error != 0 ) {
        remove( fname1 );
        remove( fname2 );
        return 1;
    }

    if ( 0 != strcmp( cert.subject, cert2.subject ) ) {
        remove( fname1 );
        remove( fname2 );
        return 1;
    }

    remove( fname1 );
    remove( fname2 );
    return 0;
}

int test_asy_key_gen(
 )
{
    xrn_matrix_t *xm;
    xnum_t cob, cos;
    xgenesis_base_t *ob;
    char fname0[256];
    char fname1[256];
    uint8_t constant_execution, force_linearity, check_sparcity;

    FILE *monomic_key_fp, *binomial_key_fp;
    int error0, error1, error2, i;

    xmonomial_key_t mkey;
    xbinomial_key_t bkey;
    xnum_t rnd, hint, tmp, tmp2;
    xstart_point_t start;
    xrn_crypto_extra_settings_t settings;

    for ( i = 0; i < sizeof( start ); i++ ) {
        ( ( uint8_t * ) & start )[i] = 0;
    }

    for ( i = 0; i < sizeof( mkey ); i++ ) {
        ( ( uint8_t * ) & mkey )[i] = 0;
    }

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    while ( settings.state_size < XRN_MIN_ALLOWED_STATE_SIZE ) {
        settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    }

    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    constant_execution = settings.const_exec_time;
    force_linearity = 1;
    check_sparcity = 0;

    // origin base
    ob = ( xgenesis_base_t * ) malloc( sizeof( xgenesis_base_t ) );
    xgenesis_base_init( ob );

    // generate xoron matrix
    xm = ( xrn_matrix_t * ) malloc( sizeof( xrn_matrix_t ) );
    xrn_initialize_rnd_num( &cob );     // change of base
    xrn_initialize_rnd_num( &cos );     // change of sign
    xgenesis_base_2_xrn_matrix( ob, &cob, &cos, xm );
    free( ob );
    xrn_initialize_rnd_num( &start.start );
    xrn_initialize_rnd_num( &mkey.distance );
    xrn_make_binomial_key( xm, start, mkey, &bkey, settings );
    strcpy( fname0, "../cache/to_remove_monomic_key.txt" );
    strcpy( fname1, "../cache/to_remove_binomial_key.txt" );
    monomic_key_fp = fopen( fname0, "wb" );

    xrn_dump_monomial_key( mkey, monomic_key_fp, settings );
    fclose( monomic_key_fp );
    binomial_key_fp = fopen( fname1, "wb" );
    xrn_dump_binomial_key( bkey, binomial_key_fp, settings );
    fclose( binomial_key_fp );
    monomic_key_fp = fopen( fname0, "rb" );
    error0 = xrn_load_monomial_key( &mkey, monomic_key_fp, &settings );
    fclose( monomic_key_fp );
    binomial_key_fp = fopen( fname1, "rb" );
    error1 = xrn_load_binomial_key( &bkey, binomial_key_fp, &settings );

    fclose( binomial_key_fp );
    remove( fname0 );
    remove( fname1 );
    xrn_initialize_rnd_num( &rnd );
    xrn_matrix_traverse( xm, &bkey.start, &rnd, &hint, &constant_execution, &force_linearity,
                         &check_sparcity );
    xrn_matrix_traverse( xm, &bkey.end, &rnd, &tmp, &constant_execution, &force_linearity, &check_sparcity );
    xrn_matrix_traverse( xm, &hint, &mkey.distance, &tmp2, &constant_execution, &force_linearity,
                         &check_sparcity );
    XNUM_CMP( tmp, tmp2, error2 );
    free( xm );

    return error0 + error1 + error2;
}

int test_binomial_key(
 )
{
    xrn_matrix_t *xm;
    xnum_t cob, cos;
    xgenesis_base_t *ob;
    char fname0[256];
    char fname1[256];
    uint8_t constant_execution, force_linearity, check_sparcity;

    FILE *monomic_key_fp, *binomial_key_fp;
    int error0, error1, error2;

    xmonomial_key_t mkey;
    xbinomial_key_t bkey;
    xnum_t rnd, hint, tmp, tmp2;
    xstart_point_t start;
    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    strcpy( settings.rnd_str, "" );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    constant_execution = settings.const_exec_time;
    force_linearity = 1;
    check_sparcity = 0;

    // origin base
    ob = ( xgenesis_base_t * ) malloc( sizeof( xgenesis_base_t ) );
    xgenesis_base_init( ob );

    // generate xoron matrix
    xm = ( xrn_matrix_t * ) malloc( sizeof( xrn_matrix_t ) );
    xrn_initialize_rnd_num( &cob );     // change of base
    xrn_initialize_rnd_num( &cos );     // change of sign
    xgenesis_base_2_xrn_matrix( ob, &cob, &cos, xm );
    free( ob );

    // generate a generator point
    xrn_make_start_point( &start, xm, settings );
    xrn_make_monomial_key( &mkey, settings );
    xrn_make_binomial_key( xm, start, mkey, &bkey, settings );
    strcpy( fname0, "../cache/to_remove_monomic_key.txt" );
    strcpy( fname1, "../cache/to_remove_binomial_key.txt" );
    monomic_key_fp = fopen( fname0, "wb" );
    xrn_dump_monomial_key( mkey, monomic_key_fp, settings );
    fclose( monomic_key_fp );
    binomial_key_fp = fopen( fname1, "wb" );
    xrn_dump_binomial_key( bkey, binomial_key_fp, settings );
    fclose( binomial_key_fp );
    monomic_key_fp = fopen( fname0, "rb" );
    error0 = xrn_load_monomial_key( &mkey, monomic_key_fp, &settings );
    fclose( monomic_key_fp );
    binomial_key_fp = fopen( fname1, "rb" );
    error1 = xrn_load_binomial_key( &bkey, binomial_key_fp, &settings );
    fclose( binomial_key_fp );
    remove( fname0 );
    remove( fname1 );
    xrn_initialize_rnd_num( &rnd );
    xrn_matrix_traverse( xm, &bkey.start, &rnd, &hint, &constant_execution, &force_linearity,
                         &check_sparcity );
    xrn_matrix_traverse( xm, &bkey.end, &rnd, &tmp, &constant_execution, &force_linearity, &check_sparcity );
    xrn_matrix_traverse( xm, &hint, &mkey.distance, &tmp2, &constant_execution, &force_linearity,
                         &check_sparcity );
    XNUM_CMP( tmp, tmp2, error2 );

    free( xm );

    return error0 + error1 + error2;
}

int test_point_io(
 )
{
    FILE *fp;
    xrn_point_t p0, p1;
    char fname[256];
    int error, error0;

    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    strcpy( fname, "../cache/to_remove_point.txt" );
    fp = fopen( fname, "wb" );
    xrn_initialize_rnd_num( &p0.point );
    xrn_dump_point( p0, fp, settings );
    fclose( fp );
    fp = fopen( fname, "rb" );
    error = xrn_load_point( &p1, fp, settings );
    fclose( fp );
    XNUM_CMP( p0.point, p1.point, error0 );
    remove( fname );
    return error + error0;
}

int test_start_point_io(
 )
{
    FILE *fp;
    xstart_point_t sp0, sp1;
    char fname[256];
    int error, error0;

    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    strcpy( fname, "../cache/to_remove_start_point.txt" );
    fp = fopen( fname, "wb" );
    xrn_initialize_rnd_num( &sp0.start );
    xrn_dump_start_point( sp0, fp, settings );
    fclose( fp );
    fp = fopen( fname, "rb" );
    error = xrn_load_start_point( &sp1, fp, &settings );
    fclose( fp );
    XNUM_CMP( sp0.start, sp1.start, error0 );
    remove( fname );
    return error + error0;
}

int test_monomic_key_io(
 )
{
    FILE *fp;
    xmonomial_key_t mkey0, mkey1;
    char fname[256];
    int error, error0;

    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    strcpy( fname, "../cache/to_remove_monomic_key.txt" );
    fp = fopen( fname, "wb" );
    xrn_initialize_rnd_num( &mkey0.distance );
    xrn_dump_monomial_key( mkey0, fp, settings );
    fclose( fp );
    fp = fopen( fname, "rb" );
    error = xrn_load_monomial_key( &mkey1, fp, &settings );
    fclose( fp );
    XNUM_CMP( mkey0.distance, mkey1.distance, error0 );
    remove( fname );
    return error + error0;
}

int test_binomial_key_io(
 )
{
    FILE *fp;
    xbinomial_key_t bkey0, bkey1;
    char fname[256];
    int error, error0, error1;

    xrn_crypto_extra_settings_t settings;

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    strcpy( fname, "../cache/to_remove_binomial_key.txt" );
    fp = fopen( fname, "wb" );
    xrn_initialize_rnd_num( &bkey0.end );
    xrn_initialize_rnd_num( &bkey0.start );
    xrn_dump_binomial_key( bkey0, fp, settings );
    fclose( fp );
    fp = fopen( fname, "rb" );
    error = xrn_load_binomial_key( &bkey1, fp, &settings );
    fclose( fp );
    XNUM_CMP( bkey0.end, bkey1.end, error0 );
    XNUM_CMP( bkey0.start, bkey1.start, error1 );
    remove( fname );
    return error0 + error1 + error;
}

int test_ring_sig_io(
 )
{
    int error, cnt0, cnt1;

    xring_signature_t sig;
    xring_signature_t sig2;
    xnum_t start;
    FILE *fpi;
    FILE *fpo;
    char fname0[256];
    char fname1[256];
    char fname2[256];
    char ch1;
    char ch2;
    int i, j;

    xrn_crypto_extra_settings_t settings;
    xrn_encoding_param_t enc_param0, enc_param1;

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;

    strcpy( fname0, "../cache/to_remove_signature_0.txt" );
    strcpy( fname1, "../cache/to_remove_signature_1.txt" );
    strcpy( fname2, "../cache/to_remove_signature_2.txt" );

    for ( i = 0; i < sizeof( sig ); i++ ) {
        ( ( uint8_t * ) & sig )[i] = 0;
        ( ( uint8_t * ) & sig2 )[i] = 0;
    }

    xrn_initialize_rnd_num( &sig.hint );
    xrn_initialize_rnd_num( &sig.proof );
    xrn_initialize_rnd_num( &start );
    sig.ring_size = 10;

    for ( int k = 0; k < sig.ring_size; k++ ) {
        sig.binomial_keys[k].start = start;
        xrn_initialize_rnd_num( &sig.binomial_keys[k].end );
    }

    fpi = fopen( fname0, "wb" );

    xrn_dump_ring_signature( sig, 0, fpi, settings );
    fclose( fpi );
    fpi = fopen( fname0, "rb" );
    xrn_load_ring_signature( &sig2, fpi, &settings );
    fclose( fpi );
    fpi = fopen( fname1, "wb" );
    xrn_dump_ring_signature( sig2, 0, fpi, settings );
    fclose( fpi );
    fpi = fopen( fname2, "wb" );
    xrn_dump_ring_signature( sig2, 1, fpi, settings );
    fclose( fpi );

    // compare the two files
    error = 0;
    i = 0;
    fpi = fopen( fname0, "rb" );
    fpo = fopen( fname1, "rb" );

    // initialize encoding interface

    xrn_initialize_encoding_parameters( &enc_param0, settings.encoding_settings.i_settings );
    xrn_initialize_encoding_parameters( &enc_param1, settings.encoding_settings.i_settings );
    j = 1;
    do {
        cnt0 = ( int ) xrn_fread_decoder( &ch1, sizeof( uint8_t ), 1, fpi, &enc_param0 );
        cnt1 = ( int ) xrn_fread_decoder( &ch2, sizeof( uint8_t ), 1, fpo, &enc_param1 );
        if ( i >= 256 ) {       // if the byte is not encoding guards
            if ( ( j != sizeof( xrn_crypto_lib_header_t ) - 1 ) && ( j != sizeof( xrn_crypto_lib_header_t ) - 0 ) ) {   // if the byte is not the crc
                // Input character from both files
                error = ( ( ch1 != ch2 ) || ( cnt0 != cnt1 ) ) || error;
            }

        } else {
            i++;
        }

        j++;

    } while ( cnt0 != 0 && cnt1 != 0 );

    fclose( fpi );
    fclose( fpo );
    if ( error != 0 ) {
        return error;
    }

    // compare the two files
    error = 0;
    i = 0;
    fpi = fopen( fname2, "rb" );
    fpo = fopen( fname1, "rb" );
    xrn_initialize_encoding_parameters( &enc_param0, settings.encoding_settings.i_settings );
    xrn_initialize_encoding_parameters( &enc_param1, settings.encoding_settings.i_settings );
    j = 1;

    do {

        // Input character from both files
        cnt0 = ( int ) xrn_fread_decoder( &ch1, sizeof( uint8_t ), 1, fpi, &enc_param0 );
        cnt1 = ( int ) xrn_fread_decoder( &ch2, sizeof( uint8_t ), 1, fpo, &enc_param1 );

        if ( i >= 256 ) {       // if the byte is not encoding guards
            if ( ( j != sizeof( xrn_crypto_lib_header_t ) - 1 ) && ( j != sizeof( xrn_crypto_lib_header_t ) - 0 ) ) {   // if the byte is not the crc
                error = ( ( ch1 != ch2 ) || ( cnt0 != cnt1 ) ) || error;

            }

        } else {
            i++;
        }

        j++;

    } while ( cnt0 != 0 && cnt1 != 0 );

    fclose( fpi );
    fclose( fpo );

    remove( fname0 );
    remove( fname1 );
    remove( fname2 );
    if ( error == 0 ) {
        return 1;
    } else {
        return 0;
    }

    return 0;
}

int test_certificate_asy(
 )
{
    FILE *fp;
    xcertificate_asy_t cert, cert2;
    time_t t;
    int error, i;
    char fname[256];

    xrn_crypto_extra_settings_t settings;

    for ( i = 0; i < sizeof( cert ); i++ ) {
        ( ( uint8_t * ) & cert )[i] = 0;
        ( ( uint8_t * ) & cert2 )[i] = 0;
    }

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;
    strcpy( fname, "../cache/to_remove_certificate_asy.txt" );
    strcpy( cert.subject, "blablabla bla" );
    xrn_initialize_rnd_num( &cert.binomial_key.end );
    cert.start_timestamp = ( uint64_t ) time( &t );
    cert.end_timestamp = ( uint64_t ) time( &t ) + 10000;
    xrn_initialize_rnd_num( &cert.signature.hint );
    xrn_initialize_rnd_num( &cert.signature.proof );
    fp = fopen( fname, "wb" );
    xrn_dump_certificate_asy( cert, fp, settings );
    fclose( fp );
    fp = fopen( fname, "rb" );
    xrn_load_certificate_asy( &cert2, fp, &settings );
    fclose( fp );
    XNUM_CMP( cert.binomial_key.end, cert2.binomial_key.end, error );
    if ( error ) {
        remove( fname );
        return 1;
    }

    XNUM_CMP( cert.binomial_key.start, cert2.binomial_key.start, error );
    if ( error ) {
        remove( fname );
        return 1;
    }

    XNUM_CMP( cert.signature.hint, cert2.signature.hint, error );
    if ( error ) {
        remove( fname );
        return 1;
    }

    XNUM_CMP( cert.signature.proof, cert2.signature.proof, error );
    if ( error ) {
        remove( fname );
        return 1;
    }

    error += cert.end_timestamp != cert2.end_timestamp;
    error += cert.start_timestamp != cert2.start_timestamp;
    if ( error != 0 ) {
        remove( fname );
        return 1;
    }

    if ( 0 != strcmp( cert.subject, cert2.subject ) ) {
        remove( fname );
        return 1;
    }

    remove( fname );
    return 0;
}

int test_encoder_table_io(
 )
{
    FILE *fp;
    xrn_encoding_param_t param1, param2;
    int error, i;
    char fname1[256];

    strcpy( fname1, "../cache/to_remove_encoding_param.txt" );

    for ( i = 0; i < 256; i++ ) {
        param1.table[i] = STD_ENC_PARAM_TABLE[i];
    }

    for ( i = 0; i < 32; i++ ) {
        ( ( uint8_t * ) & param1.prng_state[0] )[i] = ( uint8_t ) ( rand(  ) % 256 );
    }

    fp = fopen( fname1, "wb" );
    xrn_dump_encoder_parameters( param1, fp );
    fclose( fp );

    fp = fopen( fname1, "rb" );
    xrn_load_encoder_parameters( &param2, fp );
    fclose( fp );

    error = 0;
    for ( i = 0; i < 256; i++ ) {
        error = ( param1.table[i] != param2.table[i] ) || error;
    }

    for ( i = 0; i < 4; i++ ) {
        error = ( param1.prng_state[i] != param2.prng_state[i] ) || error;
    }

    remove( fname1 );

    if ( error == 1 ) {
        return 1;
    }

    return 0;
}

int test_monovalent_polyvalent_data_structures(
 )
{

    xrn_matrix_t *xrn_matrix;
    xnum_t cob, cos;
    xgenesis_base_t *ob;
    uint64_t start_timestamp;
    uint64_t end_timestamp;
    xpolyvalent_key_t polyvalent_key;
    xpolyvalent_proof_t polyvalent_proof;
    xmonovalent_key_t monovalent_key;
    xpolyvalent_key_t polyvalent_key_2;
    xpolyvalent_proof_t polyvalent_proof_2;
    xmonovalent_key_t monovalent_key_2;
    xrn_crypto_extra_settings_t settings;

    int i, error;
    char polyvalent_key_str[256];
    char polyvalent_proof_str[256];
    char monovalent_key_str[256];
    FILE *polyvalent_key_fp;
    FILE *polyvalent_proof_fp;
    FILE *monovalent_key_fp;

    settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    while ( ( settings.crc_bytes == 3 ) || ( settings.crc_bytes == 0 ) ) {
        settings.crc_bytes = ( uint8_t ) ( rand(  ) % 5 );
    }

    strcpy( settings.rnd_str, "" );
    xrn_initialize_encoding_settings( &settings.encoding_settings.i_settings );
    xrn_initialize_encoding_settings( &settings.encoding_settings.o_settings );
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    settings.state_size = ( uint8_t ) ( ( long unsigned int ) ( rand(  ) ) % ( sizeof( xnum_t ) * 8 ) );
    settings.thread_enable = ( uint8_t ) ( rand(  ) ) % 2;
    settings.const_exec_time = ( uint8_t ) ( rand(  ) ) % 2;

    strcpy( polyvalent_proof_str, "../cache/to_remove_polyvalent_proof.txt" );
    strcpy( polyvalent_key_str, "../cache/to_remove_polyvalent_key.txt" );
    strcpy( monovalent_key_str, "../cache/to_remove_monovalent_key.txt" );

    // origin base
    ob = ( xgenesis_base_t * ) malloc( sizeof( xgenesis_base_t ) );
    xgenesis_base_init( ob );

    // generate xoron matrix
    xrn_matrix = ( xrn_matrix_t * ) malloc( sizeof( xrn_matrix_t ) );
    xrn_initialize_rnd_num( &cob );     // change of base
    xrn_initialize_rnd_num( &cos );     // change of sign
    xgenesis_base_2_xrn_matrix( ob, &cob, &cos, xrn_matrix );
    free( ob );

    time( ( time_t * ) & start_timestamp );
    end_timestamp = start_timestamp + 200;

    xrn_make_monovalent_key( xrn_matrix, start_timestamp, end_timestamp, &polyvalent_key,
                             &polyvalent_proof, &monovalent_key, settings );

    free( xrn_matrix );

    // check load and store of polyvalent_key
    polyvalent_key_fp = fopen( polyvalent_key_str, "wb" );
    xrn_dump_polyvalent_key( polyvalent_key, polyvalent_key_fp, settings );
    fclose( polyvalent_key_fp );
    polyvalent_key_fp = fopen( polyvalent_key_str, "rb" );
    xrn_load_polyvalent_key( &polyvalent_key_2, polyvalent_key_fp, &settings );
    fclose( polyvalent_key_fp );
    for ( i = 0; i < XRN_STATE_KEY_SIZE; i++ ) {
        XNUM_CMP( polyvalent_key_2.state[i], polyvalent_key.state[i], error );
        if ( error == 1 ) {
            return 1;
        }

    }

    // check load and store of monovalent_key
    monovalent_key_fp = fopen( monovalent_key_str, "wb" );
    xrn_dump_monovalent_key( monovalent_key, monovalent_key_fp, settings );
    fclose( monovalent_key_fp );
    monovalent_key_fp = fopen( monovalent_key_str, "rb" );
    xrn_load_monovalent_key( &monovalent_key_2, monovalent_key_fp, &settings );
    fclose( monovalent_key_fp );
    for ( i = 0; i < XRN_STATE_KEY_SIZE; i++ ) {
        XNUM_CMP( monovalent_key_2.state[i], monovalent_key.state[i], error );
        if ( error == 1 ) {
            return 1;
        }

    }

    // check load and store of polyvalent_proof
    polyvalent_proof_fp = fopen( polyvalent_proof_str, "wb" );
    xrn_dump_polyvalent_proof( polyvalent_proof, polyvalent_proof_fp, settings );
    fclose( polyvalent_proof_fp );
    polyvalent_proof_fp = fopen( polyvalent_proof_str, "rb" );
    xrn_load_polyvalent_proof( &polyvalent_proof_2, polyvalent_proof_fp, &settings );
    fclose( polyvalent_proof_fp );
    for ( i = 0; i < XRN_STATE_KEY_SIZE; i++ ) {
        XNUM_CMP( polyvalent_proof_2.state[i], polyvalent_proof.state[i], error );
        if ( error == 1 ) {
            return 1;
        }

    }

    return 0;

}

int test_all_keys( FILE * fp, int runs, int non_block
 )
{
    time_t t;
    char buff[256];
    int v_test_monomic_key_io;
    int v_test_start_point_io;
    int v_test_point_io;
    int v_test_binomial_key_io;
    int v_test_sym_key_gen;
    int v_test_asy_key_gen;
    int v_test_binomial_key;
    int v_test_ring_sig_io;
    int v_test_certificate_asy;
    int v_test_certificate_sym;
    int v_test_encoder_table_io;
    int v_test_monovalent_polyvalent_data_structures;

    srand( ( unsigned ) time( &t ) );
    int error;
    int occ;

    error = 0;

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_ring_sig_io = test_ring_sig_io(  );
        error += v_test_ring_sig_io;
        printf( "[%4d]", occ );
        if ( !v_test_ring_sig_io ) {
            printf( "test_keys -> test_ring_sig_io passed\n" );
            fprintf( fp, "test_keys -> test_ring_sig_io passed\n" );
        } else {
            printf( "test_keys -> test_ring_sig_io failed\n" );
            fprintf( fp, "test_keys -> test_ring_sig_io failed\n" );
        }

        if ( v_test_ring_sig_io != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_sym_key_gen = test_sym_key_gen(  );
        error += v_test_sym_key_gen;
        printf( "[%4d]", occ );
        if ( !v_test_sym_key_gen ) {
            printf( "test_keys -> test_sym_key_gen passed\n" );
            fprintf( fp, "test_keys -> test_sym_key_gen passed\n" );
        } else {
            printf( "test_keys -> test_sym_key_gen failed\n" );
            fprintf( fp, "test_keys -> test_sym_key_gen failed\n" );
        }

        if ( v_test_sym_key_gen != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_monovalent_polyvalent_data_structures = test_monovalent_polyvalent_data_structures(  );
        error += v_test_monovalent_polyvalent_data_structures;
        printf( "[%4d]", occ );
        if ( !v_test_monovalent_polyvalent_data_structures ) {
            printf( "test_keys -> test_monovalent_polyvalent_data_structures passed\n" );
            fprintf( fp, "test_keys -> test_monovalent_polyvalent_data_structures passed\n" );
        } else {
            printf( "test_keys -> test_monovalent_polyvalent_data_structures failed\n" );
            fprintf( fp, "test_keys -> test_monovalent_polyvalent_data_structures failed\n" );
        }

        if ( v_test_monovalent_polyvalent_data_structures != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_binomial_key = test_binomial_key(  );
        error += v_test_binomial_key;
        printf( "[%4d]", occ );
        if ( !v_test_binomial_key ) {
            printf( "test_keys -> test_binomial_key passed\n" );
            fprintf( fp, "test_keys -> test_binomial_key passed\n" );
        } else {
            printf( "test_keys -> test_binomial_key failed\n" );
            fprintf( fp, "test_keys -> test_binomial_key failed\n" );
        }

        if ( v_test_binomial_key != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_asy_key_gen = test_asy_key_gen(  );
        error += v_test_asy_key_gen;
        printf( "[%4d]", occ );
        if ( !v_test_asy_key_gen ) {
            printf( "test_keys -> test_asy_key_gen passed\n" );
            fprintf( fp, "test_keys -> test_asy_key_gen passed\n" );
        } else {
            printf( "test_keys -> test_asy_key_gen failed\n" );
            fprintf( fp, "test_keys -> test_asy_key_gen failed\n" );
        }

        if ( v_test_asy_key_gen != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_point_io = test_point_io(  );
        error += v_test_point_io;
        printf( "[%4d]", occ );
        if ( !v_test_point_io ) {
            printf( "test_keys -> test_point_io passed\n" );
            fprintf( fp, "test_keys -> test_point_io passed\n" );
        } else {
            printf( "test_keys -> test_point_io failed\n" );
            fprintf( fp, "test_keys -> test_point_io failed\n" );
        }

        if ( v_test_point_io != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_encoder_table_io = test_encoder_table_io(  );
        error += v_test_encoder_table_io;
        printf( "[%4d]", occ );
        if ( !v_test_encoder_table_io ) {
            printf( "test_keys -> test_encoder_table_io passed\n" );
            fprintf( fp, "test_keys -> test_encoder_table_io passed\n" );
        } else {
            printf( "test_keys -> test_encoder_table_io failed\n" );
            fprintf( fp, "test_keys -> test_encoder_table_io failed\n" );
        }

        if ( v_test_encoder_table_io != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_monomic_key_io = test_monomic_key_io(  );
        error += v_test_monomic_key_io;
        printf( "[%4d]", occ );
        if ( !v_test_monomic_key_io ) {
            printf( "test_keys -> test_monomic_key_io passed\n" );
            fprintf( fp, "test_keys -> test_monomic_key_io passed\n" );
        } else {
            printf( "test_keys -> test_monomic_key_io failed\n" );
            fprintf( fp, "test_keys -> test_monomic_key_io failed\n" );
        }

        if ( v_test_monomic_key_io != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_start_point_io = test_start_point_io(  );
        error += v_test_start_point_io;
        printf( "[%4d]", occ );
        if ( !v_test_start_point_io ) {
            printf( "test_keys -> test_start_point_io passed\n" );
            fprintf( fp, "test_keys -> test_start_point_io passed\n" );
        } else {
            printf( "test_keys -> test_start_point_io failed\n" );
            fprintf( fp, "test_keys -> test_start_point_io failed\n" );
        }

        if ( v_test_start_point_io != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_certificate_sym = test_certificate_sym(  );
        error += v_test_certificate_sym;
        printf( "[%4d]", occ );
        if ( !v_test_certificate_sym ) {
            printf( "test_keys -> test_certificate_sym  passed\n" );
            fprintf( fp, "test_keys -> test_certificate_sym  passed\n" );
        } else {
            printf( "test_keys -> test_certificate_sym  failed\n" );
            fprintf( fp, "test_keys -> test_certificate_sym  failed\n" );
        }

        if ( v_test_certificate_sym != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_certificate_asy = test_certificate_asy(  );
        error += v_test_certificate_asy;
        printf( "[%4d]", occ );
        if ( !v_test_certificate_asy ) {
            printf( "test_keys -> test_certificate_asy  passed\n" );
            fprintf( fp, "test_keys -> test_certificate_asy  passed\n" );
        } else {
            printf( "test_keys -> test_certificate_asy  failed\n" );
            fprintf( fp, "test_keys -> test_certificate_asy  failed\n" );
        }

        if ( v_test_certificate_asy != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    for ( occ = 0; ( occ < runs ) && ( ( error == 0 ) || non_block ); occ++ ) {
        srand( ( unsigned ) time( &t ) + ( unsigned ) occ );
        v_test_binomial_key_io = test_binomial_key_io(  );
        error += v_test_binomial_key_io;
        printf( "[%4d]", occ );
        if ( !v_test_binomial_key_io ) {
            printf( "test_keys -> test_binomial_key_io passed\n" );
            fprintf( fp, "test_keys -> test_binomial_key_io passed\n" );
        } else {
            printf( "test_keys -> test_binomial_key_io failed\n" );
            fprintf( fp, "test_keys -> test_binomial_key_io failed\n" );
        }

        if ( v_test_binomial_key_io != 0 ) {
#if ( XRN_GNU_LINUX == 1 )
            sprintf( buff, "TEST_KEYS FAILED SEED %ld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %ld \n", t );
#else
            sprintf( buff, "TEST_KEYS FAILED SEED %lld ", t );
            fprintf( fp, "TEST_KEYS FAILED SEED %lld \n", t );
#endif
            printf( "%s", buff );
        }

    }

    return error;
}

